package com.hyt.it.ogt.ykcj.task;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.Assert;

import com.hyt.it.ogt.ykcj.domain.system.SysScheduledCron;
import com.hyt.it.ogt.ykcj.mapper.system.SysScheduledCronMapper;

//@Configuration      //1.主要用于标记配置类，兼备Component的效果。
//@EnableScheduling   // 2.开启定时任务
public class ScheduleTaskConfig implements SchedulingConfigurer {


    @Autowired      //注入mapper
    private SysScheduledCronMapper cronMapper;
    @Autowired
    private ApplicationContext context;


    /**
     * 执行定时任务.
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        List<SysScheduledCron> list = cronMapper.selectSysScheduledCronList(new SysScheduledCron());
        for (SysScheduledCron cron:list) {
            Class<?> clazz;
            Object task;
            try {
                clazz = Class.forName(cron.getCronKey());
                task = context.getBean(clazz);
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("spring_scheduled_cron表数据" + cron.getCronKey() + "有误", e);
            } catch (BeansException e) {
                throw new IllegalArgumentException(cron.getCronKey() + "未纳入到spring管理", e);
            }
            Assert.isAssignable(ScheduledOfTask.class, task.getClass(), "定时任务类必须实现ScheduledOfTask接口");
            taskRegistrar.addTriggerTask(
                    //1.添加任务内容(Runnable)
                    (((Runnable) task)),
                    //2.设置执行周期(Trigger)
                    triggerContext -> {
                        //2.1 从数据库获取执行周期
                        //2.2 合法性校验.
                        System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime());
                        //2.3 返回执行周期(Date)
                        String cronExpression = cronMapper.findByCronKey(cron.getCronKey()).getCronExpression();
                        return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
                    }


            );
        }
    }

}